//
//  PhotoManager+Import.swift
//  UILibrarysKit
//
//  Created by TSYH on 2024/5/14.
//

import UIKit
import AVFoundation
import PhotosUI
import THUD
import ExtensionsKit

public enum ImportSource {
    case file       // 文件
    case library    // 相册
}

public enum ResourceType: String {
    case mp3            = "public.mp3"
    case mov            = "public.movie"
}

public struct ImportResultItem {
    public let url: URL
    public let localIdentifier: String
    
    public init(url: URL, localIdentifier: String) {
        self.url = url
        self.localIdentifier = localIdentifier
    }
}

public typealias ImportCompletionHandler = ([ImportResultItem]?, String?) -> Void

public extension PhotoManager {
    /// 打开File picker
    /// - Parameters:
    ///   - types: 支持选择的资源类型
    ///   - completion: 完成 (temp临时文件URL， Error)
    func openFilePicker(types: [ResourceType], completion: ImportCompletionHandler?) {
        let documentTypes = types.map({ $0.rawValue })
        // 音频 mp3，wav，m4a
        // .MP3; .AAC; .WAV; .WMA; .CDA; .FLAC; .M4A; .MID; .MKA; .MP2; .MPA; .MPC; .APE; .OFR; .OGG; .RA; .WV; .TTA; .AC3; .DTS
        // 视频 mp4，avi, wmv，mov，mpg(mpeg)
        let documentVC = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
//        Appropriate
//        let documentVC = UIDocumentPickerViewController(forOpeningContentTypes: [.aiff, .audio, .avi, .wav, .mp3, .movie])
        documentVC.delegate = self
        documentVC.modalPresentationStyle = .fullScreen
        UIApplication.topViewController?.present(documentVC, animated: true)
        importCompletionHandler = completion
        
        PHPhotoLibrary.requestAuthorization { [weak self] status in
            DispatchQueue.main.async {
                if status == .authorized || status == .limited {
                }
                else {
                }
            }
        }
    }
    
    /// 打开照片picker
    /// - Parameters:
    ///   - filter: 筛选文件类型
    ///   - importingHandler: 开始加载相册视频，显示loading
    ///   - completion: 完成 (temp临时文件URL， Error)
    func openPhotoLibrary(filter: PHPickerFilter, 
                          importingHandler: (() -> Void)?,
                          completion: ImportCompletionHandler?) {
        importCompletionHandler = completion
        self.importingHandler = importingHandler
        
        let openHandler = {
            var config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
            config.filter = filter
            config.selectionLimit = 9
            let pickerVC = PHPickerViewController(configuration: config)
            pickerVC.modalPresentationStyle = .fullScreen
            pickerVC.delegate = self
            UIApplication.topViewController?.present(pickerVC, animated: true)
        }
        
        PHPhotoLibrary.requestAuthorization { [weak self] status in
            DispatchQueue.main.async {
                if status == .authorized || status == .limited {
                    openHandler()
                }
                else {
                    self?.showPhotoPermissionAlert(message: "No album permission, turn it on to import files")
                }
            }
        }
    }
    
    // 批量读取相册视频文件
    func fetchVideosFromLibrary(startHandler: (() -> Void)?, progressHandler: ((CGFloat) -> Void)?, completionHandler: (([ImportResultItem]?) -> Void)?) {
        let fetchHandler = {
            let fetchOptions = PHFetchOptions()
            fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.video.rawValue)
            fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
            let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: fetchOptions)
            
            let group = DispatchGroup()
            let queue = DispatchQueue(label: "queue_fetch_videos")
            var result = [ImportResultItem]()
            
//            let options = PHVideoRequestOptions()
//            options.isNetworkAccessAllowed = true
//            options.deliveryMode = .mediumQualityFormat // iCloud画质
            var finishedCount = 0
            
            let options = PHVideoRequestOptions()
            options.isNetworkAccessAllowed = false
            options.deliveryMode = .highQualityFormat
            
            if fetchResult.count > 0 {
                for i in 0..<fetchResult.count {
                    let asset = fetchResult.object(at: i)
//                    Log("====id: \(asset.localIdentifier)")
                    let phResource = PHAssetResource.assetResources(for: asset)
                    let isLocal = phResource.first?.value(forKey: "locallyAvailable") as? Bool ?? false
                    Log("===local: \(isLocal)")
                    
                    if isLocal {
                        group.enter()
                        queue.async {
                            PHImageManager.default().requestPlayerItem(forVideo: asset, options: options) { playItem, info in
                                guard let playItem = playItem, playItem.error == nil else {
                                    return
                                }
                                Log("===YES")
                            }
                            PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { avAsset, audioMix, info in
                                if let avUrlAsset = avAsset as? AVURLAsset,
                                   FileManager.default.fileExists(atPath: avUrlAsset.url.path),
                                    FileManager.default.isReadableFile(atPath: avUrlAsset.url.path),
                                    CMTimeGetSeconds(avUrlAsset.duration) > 0 {
    //                                Log("avAsset URL: \(avUrlAsset.url)")
                                    result.append(ImportResultItem(url: avUrlAsset.url, localIdentifier: asset.localIdentifier))
                                    Log("videoURL: \(avUrlAsset.url)")
                                } else {
//                                Log("info: \(info)")
                                }
                                finishedCount += 1
    //                            Log("==: \(finishedCount)/\(fetchResult.count)")
                                progressHandler?(CGFloat(finishedCount)/CGFloat(fetchResult.count))
                                group.leave()
                            }
                        }
                    }
                }
            }
            
            group.notify(queue: queue) {
                Log("findCount: \(finishedCount)")
                completionHandler?(result)
            }
        }
        
        PHPhotoLibrary.requestAuthorization { [weak self] status in
            DispatchQueue.main.async {
                if status == .authorized || status == .limited {
                    startHandler?()
                    fetchHandler()
                } else {
                    self?.showPhotoPermissionAlert(message: "No album permission, turn it on to import files")
                    completionHandler?(nil)
                }
            }
        }
    }
}

extension PhotoManager: UIDocumentPickerDelegate {
    public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        importCompletionHandler?(urls.map({ ImportResultItem(url: $0, localIdentifier: "") }), nil)
    }
    
    public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        importCompletionHandler?(nil, "")
    }
}

extension PhotoManager {
    // 照片选择导入视频处理逻辑
    func handlerPhotoPickerByImport(results: [PHPickerResult]) {
        guard !results.isEmpty else {
            importCompletionHandler?(nil, "")
            return
        }
        
        let group = DispatchGroup()
        let queue = DispatchQueue(label: "queue_load_picker_result")
        
        var urls = [ImportResultItem]()
        var errorMsg: String?
        
        let identifiers = results.compactMap(\.assetIdentifier)
        let assetResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
        for index in 0..<assetResult.count {
            let asset = assetResult.object(at: index)
            
            group.enter()
            queue.async {
                PHCachingImageManager.default().requestAVAsset(forVideo: asset, options: nil) { avAsset, audioMix, info in
                    if let avUrlAsset = avAsset as? AVURLAsset {
                        Log("avAsset URL: \(avUrlAsset.url)")
                        urls.append(ImportResultItem(url: avUrlAsset.url, localIdentifier: asset.localIdentifier))
                    } else {
                        errorMsg = "Import failed, because the video is saved in iCloud"
                    }
                    group.leave()
                }
            }
        }
        group.notify(queue: queue) { [weak self] in
            self?.importCompletionHandler?(urls, errorMsg)
        }
    }
    
    public func cancelImport() {
        currentImportProgress?.cancel()
        currentImportProgress = nil
    }
}

extension PhotoManager {
    // 导入文件处理
//    func handlerPickerResult(fileURL: URL) {
//        Log("==picker: \(fileURL.path)")
//        Log("==file type: \(fileURL.pathExtension)")
//        
//        let fileType = fileURL.pathExtension
//        if fileType.lowercased() == "mp3" {
//            // 音频
//            copyAudio(from: fileURL) { [weak self] resultURL, errMsg in
//                self?.saveImportAudio(with: resultURL)
//                self?.importCompletionHandler?(resultURL != nil, errMsg)
//            }
//        } else {
//            // 视频
//            var completionHandler: AudioCompletionHandler? = { [weak self] url, error in
//                DispatchQueue.main.async {
//                    THUD.hide()
//                }
//                self?.saveImportAudio(with: url)
//                self?.importCompletionHandler?(url != nil, error)
//            }
//            DispatchQueue.main.async {
//                THUD.showLoading("Importing...") { [weak self] in
//                    THUD.hide()
//                    // 取消
//                    self?.audioConvertTool.cancelTask = true
//                    completionHandler = nil
//                }
//            }
//            extractAudioFromVideo(sourceFileURL: fileURL) { resultURL, errMsg in
//                completionHandler?(resultURL, errMsg)
//            }
//        }
//    }
    
    // 复制音频文件
//    func copyAudio(from sourceFileURL: URL,
//                   completion: AudioCompletionHandler?) {
//        let fromPath = sourceFileURL.path
//        // lastPathComponent 自动 removingPercentEncoding
//        let fileName = sourceFileURL.lastPathComponent
//        guard FileManager.default.fileExists(atPath: fromPath) else {
//            completion?(nil, "File Don't exist, try another")
//            return
//        }
//        guard let toPath = self.getCopyToPath(with: fileName) else {
//            completion?(nil, "Sorry, Unable To Copy File")
//            return
//        }
//        do {
//            try FileManager.default.copyItem(atPath: fromPath, toPath: toPath)
//            if FileManager.default.fileExists(atPath: toPath) {
//                Log("===copy successfully")
//                
//                let fileUrl = URL(fileURLWithPath: toPath)
//                completion?(fileUrl, nil)
//            }
//        } catch let error {
//            Log("\(error.localizedDescription)")
//            completion?(nil, error.localizedDescription)
//        }
//    }
    
    /// 从视频中提取音频，转为mp3
    /// 先把源文件copy到app内
//    func extractAudioFromVideo(sourceFileURL: URL,
//                               completion: AudioCompletionHandler?) {
//        let videoFileName = sourceFileURL.lastPathComponent
//        guard FileManager.default.fileExists(atPath: sourceFileURL.path),
//                let copyVideoPath = getCopyToPath(with: videoFileName) else {
//            completion?(nil, "Sorry, File don`t exist, try another")
//            return
//        }
//        try? FileManager.default.copyItem(atPath: sourceFileURL.path, toPath: copyVideoPath)
//        guard FileManager.default.fileExists(atPath: copyVideoPath) else {
//            completion?(nil, "Sorry, Copy File Failure")
//            return
//        }
//        let videoUrl = URL(fileURLWithPath: copyVideoPath)
//        
//        let mp3FileName = videoUrl.deletingPathExtension().lastPathComponent
//        guard let mp3Path = getCopyToPath(with: "\(mp3FileName).mp3") else {
//            completion?(nil, "Sorry, Unable To Copy File")
//            return
//        }
//        let mp3URL = URL(fileURLWithPath: mp3Path)
//        audioConvertTool.cancelTask = false
//        audioConvertTool.convertToMp3FromVideo(fileURL: videoUrl, outputURL: mp3URL) { mp3URL, errMsg in
//            completion?(mp3URL, errMsg)
//        }
//    }
}

//extension PhotoManager {
//    // 根据文件名获取粘贴地址，如果已存在同名，则拼接后缀：-1。-2
//    func getCopyToPath(with fileName: String,
//                       subfix: Int = 0) -> String? {
//        guard let documentPath = ringDirectory,
//              let document = URL(string: documentPath) else {
//            return nil
//        }
//        let fileName = fileName.removingPercentEncoding ?? fileName
//        
//        // appendingPathComponent 会对文件名进行编码
//        var url = document.appendingPathComponent(fileName)
//        let fileType = url.pathExtension
//        url.deletePathExtension()
//        var urlString = url.path
//        if subfix > 0 {
//            urlString.append("-\(subfix)")
//        }
//        
//        let newUrl = URL(fileURLWithPath: urlString).appendingPathExtension(fileType)
//        
//        // 反编码
//        let newPath = newUrl.path.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
//        if FileManager.default.fileExists(atPath: newPath!) {
//            return getCopyToPath(with: fileName, subfix: subfix+1)
//        }
//        Log("===toPath: \(newPath)")
//        // 返回已编码路径
//        return newPath
//    }
//}
